package cn.txy.service.impl;

import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.txy.constants.Constants;
import cn.txy.domain.OpenIdResult;
import cn.txy.mapper.PermissionMapper;
import cn.txy.pojo.domain.Login;
import cn.txy.mapper.LoginMapper;
import cn.txy.pojo.domain.Permission;
import cn.txy.pojo.dto.LoginDto;
import cn.txy.pojo.dto.SystemLoginDto;
import cn.txy.pojo.vo.LoginSuccessVo;
import cn.txy.service.ILoginService;
import cn.txy.template.WechatLoginTemplate;
import cn.txy.utils.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.AccessType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {

    @Autowired
    private WechatLoginTemplate wechatLoginTemplate;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public LoginSuccessVo login(LoginDto dto) {

        String code = dto.getCode();
        OpenIdResult openId = wechatLoginTemplate.getOpenId(code);
        AssertUtil.isNotEmpty(openId.getOpenId(), "微信ID不能为空");
        Login one = super.getOne(new LambdaQueryWrapper<Login>()
                .eq(Login::getOpenId, openId.getOpenId())
                .eq(Login::getType, dto.getType()));
        AssertUtil.isNotNull(one, "请先注册");

//        StpUtil.login(one.getId());
        return getLoginSuccessVo(one);
    }

    private LoginSuccessVo getLoginSuccessVo(Login one) {
        SaTokenInfo saTokenInfo = saTokenLogin(one);

        LoginSuccessVo loginSuccessVo = new LoginSuccessVo();
        loginSuccessVo.setAvatar(one.getAvatar());
        loginSuccessVo.setNickName(one.getNickName());
        loginSuccessVo.setPhone(one.getPhone());

        loginSuccessVo.setToken(saTokenInfo);

        //保存用户和权限
        List<String> loginRole = loginMapper.getLoginRole(one.getId());
        List<String> loginPermissions = null;
        if (one.getUsername().equals(Constants.System.SYSTEM_ADMIN)){
            List<Permission> permissions = permissionMapper.selectList(new LambdaQueryWrapper<>());
            loginPermissions = permissions.stream().map(Permission::getSn).collect(Collectors.toList());
        }else {
            loginPermissions = loginMapper.getLoginPermissions(one.getId());
        }
        redisTemplate.opsForValue().set(Constants.redis.USER_ROLE+ one.getId().toString(),loginRole);
        redisTemplate.opsForValue().set(Constants.redis.USER_PERMISSION+ one.getId().toString(),loginPermissions);
        loginSuccessVo.setPermissions(loginPermissions);
        one.setPassword(null);
        one.setOpenId(null);
        loginSuccessVo.setLogin(one);

        return loginSuccessVo;
    }

    @Override
    public LoginSuccessVo systemLogin(SystemLoginDto of) {
        String username = of.getUsername();
        Login one = super.getOne(new LambdaQueryWrapper<Login>()
                        .eq(Login::getType,of.getType())
                .eq(Login::getUsername, username)
                .or()
                .eq(Login::getPhone, username)
        );
        AssertUtil.isNotNull(one,"用户名或密码错误");
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(of.getPassword(), one.getPassword());
        AssertUtil.isTrue(matches,"用户名或密码错误");
        return getLoginSuccessVo(one);
    }

    public SaTokenInfo saTokenLogin(Login login){
        StpUtil.login(login.getId(), SaLoginConfig
                //根据需要封装扩展参数
                .setExtra("username", login.getUsername())
                .setExtra("type", login.getType())
                .setExtra("avatar", login.getAvatar())
                .setExtra("admin", login.getAdmin())
                .setExtra("nickName", login.getNickName())
                //加载权限
                .setExtra("permissions", StpUtil.getPermissionList(login.getId()))
                .setExtra("roles", StpUtil.getRoleList(login.getId()))
                .setExtra("openId", login.getOpenId()));
        return StpUtil.getTokenInfo();
    }
}
